<?php
namespace App\Factory\Payment;

use App\Factory\Wechat\Factory as WechatFactory;
use App\Utils\Other\Safepay\Payment\Mini as SafepayMini;
use App\Utils\Other\Payment\Sandpay\Mini as SandpayMini;
use App\Utils\Other\Payment\Neopay\Mini as NeopayMini;
use App\Utils\Other\Payment\Sumpay\Mini as SumpayMini;
use App\Utils\Other\Payment\Chinapnrpay\Mini as ChinapnrpayMini;
use Hyperf\Context\Context;
use function Hyperf\Support\make;

Class Factory {

//    /**
//     * 衫德微信小程序支付
//     * @param array $params
//     * @return array
//     * @throws \GuzzleHttp\Exception\GuzzleException
//     */
//    public function sandpayMini(array $params):array
//    {
//        /** @var Mini $miniPay */
//        $miniPay = make(Mini::class);
//
//        $params['totalAmount'] = str_pad($params['amount'] * 100, 12, '0', STR_PAD_LEFT);
//        $params['orderCode'] = $params['out_trade_no'];
//        $params['orderBody'] = $params['description'];
//
//        unset($params['amount'], $params['out_trade_no'], $params['description']);
//
//        return $miniPay->handle($params);
//    }

    /**
     * 微信小程序支付
     * @param array $params
     * @return array
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
     */
    public function wechatMini(array $params):array
    {
        $config = Context::get('pay_config_array');
        /** @var WechatFactory $pay */
        $pay = make(WechatFactory::class);
        $app = $pay->pay($config);
        $account = $app->getMerchant();

        $params['appid'] = $config['app_id'];
        $params['mchid'] = (string)$account->getMerchantId();

        $client = $app->getClient()
            ->withSerialHeader(array_key_first($config['platform_certs']));
        $response = $client->postJson('v3/pay/transactions/jsapi', $params);

        try {
            $data = $response->toArray();
            $app->getValidator()->validate($response->toPsrResponse());
        } catch (\Throwable $throwable) {
            logs($response->getContent(false));
            throw $throwable;
        }

        $prepayId = $data['prepay_id'];

        $utils = $app->getUtils();
        $config = $utils->buildMiniAppConfig($prepayId, $config['app_id']);

        return [
            $params, $response->toArray(), $config,
            'https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi'
        ];
    }

    /**
     * safepay小程序支付
     * @param array $params
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function safepayMini(array $params, string $appId = ''):array
    {
        /** @var SafepayMini $miniPay */
        $miniPay = make(SafepayMini::class);

        $params['tradeamt'] = $params['amount'];
        $params['orderCode'] = $params['out_trade_no'];
        $params['body'] = $params['description'];
        $params['payId'] = '11';

        unset($params['amount'], $params['out_trade_no'], $params['description']);

        return $miniPay->handle($params, $appId);
    }

    /**
     * 易生小程序支付
     * @param array $params
     * @param string $appId
     * @return array
     */
    public function neopayMini(array $params, string $appId = ''):array
    {
        /** @var NeopayMini $mini */
        $mini = make(NeopayMini::class);
        $mini->setConfig(Context::get('pay_config_array'));
        if ($appId) {
            $mini->setConfig(['app_id' => $appId]);
        }

        return $mini->pay($params);
    }

    /**
     * 衫德小程序支付
     * @param array $params
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sandpayMini(array $params): array
    {
        /** @var SandpayMini $mini */
        $mini = make(SandpayMini::class);
        $mini->setConfig(Context::get('pay_config_array'));

        $params['mid'] = $mini->getConfig('mid');
        $params['description'] = $mini->getConfig('app_name').'-'.$params['description'];

        return $mini->pay($params);
    }

    /**
     * 衫德小程序支付回调通知
     * @param array $params
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sandpayMiniNotify(array $params, array $config): array
    {
        /** @var SandpayMini $mini */
        $mini = make(SandpayMini::class);
        $mini->setConfig($config);

        return $mini->verify($params);
    }

    /**
     * 统统付小程序支付
     * @param array $params
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function sumpayMini(array $params): array
    {
        /** @var SumpayMini $mini */
        $mini = make(SumpayMini::class);
        $mini->setConfig(Context::get('pay_config_array'));

        return $mini->pay($params);
    }

    /**
     * 统统付微信小程序支付回调通知
     * @param array $params
     * @param array $config
     * @return array
     */
    public function sumpayMiniNotify(array $params, array $config): array
    {
        /** @var SumpayMini $mini */
        $mini = make(SumpayMini::class);
        $mini->setConfig($config);

        return $mini->verify($params);
    }

    /**
     * 汇付小程序支付
     * @param array $params
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function chinapnrpayMini(array $params): array
    {
        /** @var ChinapnrpayMini $mini */
        $mini = make(ChinapnrpayMini::class);
        $mini->setConfig(Context::get('pay_config_array'));

        return $mini->pay($params);
    }

    /**
     * 汇付小程序支付回调通知
     * @param array $params
     * @param array $config
     * @return array
     */
    public function chinapnrpayMiniNotify(array $params, array $config): array
    {
        /** @var ChinapnrpayMini $mini */
        $mini = make(ChinapnrpayMini::class);
        $mini->setConfig($config);

        return $mini->verify($params);
    }
}